package com.tarena.lbs.activity.api.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import com.tarena.lbs.activity.api.mapper.ActivityApiMapper;
import com.tarena.lbs.activity.api.pojo.ActivityDto;
import com.tarena.lbs.activity.api.service.ActivityApiService;
import com.tarena.lbs.common.entity.Activity;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;


@Service
@Slf4j  // Lombok 日志注解
public class ActivityApiServiceImpl implements ActivityApiService {

    @Autowired
    private ActivityApiMapper activityMapper;

    @Autowired
    private WebClient webClient;

    @Value("http://localhost:8081") // 从配置读取服务地址
    private String userServiceBaseUrl;

    // 检查活动是否存在
    private Activity checkActivityExists(Long activityId) {
        LambdaQueryWrapper<Activity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Activity::getId, activityId)
                .eq(Activity::getIsValid, 1);
        Activity activity = activityMapper.selectOne(wrapper);
        if (activity == null) {
            throw new RuntimeException("活动不存在或已失效");
        }
        return activity;
    }

    // 改进后的方法（返回 Mono<Boolean> 支持响应式）
    @Override
    public Mono<Boolean> checkUserInActivityReactive(Long activityId, Long userId) {
        return Mono.fromCallable(() -> checkActivityExists(activityId))
                .flatMap(activity -> {
                    String targetGroups = activity.getTargetUserGroups();
                    if (!StringUtils.hasText(targetGroups)) {
                        return Mono.just(true);  // 无限制，允许所有用户
                    }

                    // 异步调用用户服务
                    return webClient.get()
                            .uri(userServiceBaseUrl + "/user/groups/{userId}", userId)
                            .accept(MediaType.APPLICATION_JSON)
                            .retrieve()
                            .onStatus(HttpStatus::isError, response -> {
                                log.error("获取用户组失败，状态码: {}", response.statusCode());
                                return Mono.error(new RuntimeException("用户服务不可用"));
                            })
                            .bodyToMono(ActivityDto.class)
                            .map(response -> {
                                List<String> userGroups = response.getGroups();
                                if (userGroups == null || userGroups.isEmpty()) {
                                    return false;
                                }

                                // 预处理目标组（去重、去空）
                                Set<String> targetGroupSet = Arrays.stream(targetGroups.split(","))
                                        .map(String::trim)
                                        .filter(StringUtils::hasText)
                                        .collect(Collectors.toSet());

                                // 检查是否有交集
                                return userGroups.stream()
                                        .anyMatch(targetGroupSet::contains);
                            })
                            .onErrorResume(e -> {
                                log.error("调用用户服务异常", e);
                                return Mono.just(false);  // 失败时默认拒绝
                            });
                });
    }
    // 兼容旧版（同步阻塞方式）
    @Override
    public boolean checkUserInActivity(Long activityId, Long userId) {
        try {
            return checkUserInActivityReactive(activityId, userId).block();
        } catch (Exception e) {
            log.error("检查用户活动权限异常", e);
            return false;
        }
    }
}
